#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import threading
import json
from collections import OrderedDict

import Take6Server
import RoomManage
import GameManage
import UserDataManage

KEY_PLAYER_NAME = "playerName"

class PlayerInfo:
    PlayerName = ""
    PlayerIcon = 0
    PlayerStartScore = 100

class PlayerManage(threading.Thread):
    def __init__(self, connection, roomManager):
        threading.Thread.__init__(self)
        self.con = connection
        self.m_roomManager = roomManager
        self.m_nRoomID = 0
        self.m_opponents = []
        self.m_gameManage = False
        self.m_nPlayerCount = 0
        self.m_strPlayerName = ""
        self.m_nPlayerIcon = 0
        self.m_nPlayerStarScore = 100
        self.m_nPlayerIndex = -1
        self.m_bIsAI = False
        self.m_bIsTemp = False
        self.m_kickTimer = {}
        self.m_dataManager = None
    
    def run(self):
        while True:
            try:
                recv_message = Take6Server.recv_data(self.con, 10000)
                print recv_message
                if (recv_message):
                    
                    if UserDataManage.checkIsUserDataMessage(recv_message):
                        code = UserDataManage.getUserCode(recv_message)
                        self.m_dataManager = UserDataManage.UserDataManage(code)
                        strUserDataMessage = UserDataManage.getUserDataMessage(self.m_dataManager)
                        Take6Server.send_data(self.con, strUserDataMessage)
                    
                    elif self.m_roomManager.checkIsRoomMessage(recv_message):
                        #1 create room
                        if self.m_roomManager.getRoomMessageType(recv_message) == RoomManage.MessageType.MESSAGE_ROOM_CREATE:
                            
                            (nRoomID, nPlayerCount, strPlayerName, nPlayerIcon, strRoomMessage) = self.m_roomManager.createRoom(recv_message, self)
                            self.m_nRoomID = nRoomID
                            self.m_nPlayerCount = nPlayerCount
                            self.m_nPlayerIndex = 0
                            self.m_strPlayerName = strPlayerName
                            self.m_nPlayerIcon = nPlayerIcon
                            Take6Server.send_data(self.con, strRoomMessage)
                        #2 join room
                        elif self.m_roomManager.getRoomMessageType(recv_message) == RoomManage.MessageType.MESSAGE_ROOM_JOIN:
                            (nRoomID, nPlayerCount, nCurrentPlayerCount, strPlayerName, nPlayerIcon, strRoomMessage) = self.m_roomManager.joinRoom(recv_message, self)

                            if nRoomID == -1:
                                Take6Server.send_data(self.con, strRoomMessage)
                                continue
                            
                            self.m_nRoomID = nRoomID
                            self.m_nPlayerCount = nPlayerCount
                            self.m_nPlayerIndex = nCurrentPlayerCount - 1
                            self.m_strPlayerName = strPlayerName
                            self.m_nPlayerIcon = nPlayerIcon
                            Take6Server.send_data(self.con, strRoomMessage)
                            if nPlayerCount == nCurrentPlayerCount:
                                self.firsStartGame(nRoomID)
                            else:
                                rgPlayers = self.m_roomManager.getPlayers(nRoomID)
                                for player in rgPlayers:
                                    if player != self :
                                        player.sendGameMessage(strRoomMessage)
                        #3 exit room
                        elif self.m_roomManager.getRoomMessageType(recv_message) == RoomManage.MessageType.MESSAGE_ROOM_EXIT:
                            self.m_roomManager.playerLeftRoom(self, self.m_nRoomID)
                            Take6Server.send_data(self.con, recv_message)
                
                        #4 return room
                        elif self.m_roomManager.getRoomMessageType(recv_message) == RoomManage.MessageType.MESSAGE_ROOM_RETURN:
                            dicJsonMessage = json.loads(recv_message)
                            nRoomID = dicJsonMessage[RoomManage.KEY_ROOM_ID]
                            nPlayerIndex = dicJsonMessage[RoomManage.KEY_PLAYER_INDEX]
                            (strRoomMessage, gameManage) = self.m_roomManager.returnRoom(nRoomID, nPlayerIndex, self)
                            self.m_gameManage = gameManage
                            if self.m_gameManage != False:
                                self.m_nRoomID = nRoomID
                                self.m_nPlayerIndex = nPlayerIndex
                            Take6Server.send_data(self.con, strRoomMessage)
            
                        #5 kick out room
                        elif self.m_roomManager.getRoomMessageType(recv_message) == RoomManage.MessageType.MESSAGE_ROOM_KICKOUT:
                            dicJsonMessage = json.loads(recv_message)
                            nKickPlayerIndex = dicJsonMessage[RoomManage.KEY_PLAYER_INDEX]
                            rgPlayers = self.m_roomManager.getPlayers(nRoomID)
                            player = rgPlayers[nKickPlayerIndex]
                            if self.__checkPlayerNeedBeKicked(nKickPlayerIndex):
                                kickTimer = threading.Timer(3, self.__kickPlayerOut, [player])
                                kickTimer.start()
                                print "kick timer start..."
                                self.m_kickTimer[nKickPlayerIndex] = kickTimer
                            
                    elif self.m_gameManage != False and self.m_gameManage.checkIsGameMessage(recv_message):
                        dicJsonMessage = json.loads(recv_message)
                        nPlayerIndex = dicJsonMessage[RoomManage.KEY_PLAYER_INDEX]
                        if self.m_kickTimer.has_key(nPlayerIndex):
                            self.m_kickTimer[nKickPlayerIndex].cancel()
                        
                        strGameMessage = self.m_gameManage.receiveAMessage(recv_message)
                        Take6Server.send_data(self.con, strGameMessage)
                        
                        for opponent in self.m_opponents:
                            opponent.sendGameMessage(strGameMessage)

                    else:
                        print "get an invalid message"
                        Take6Server.send_data(self.con, self.__pauseMessage())

                else:
                    print "close socket"
                    self.m_roomManager.playerLeftRoom(self, self.m_nRoomID)
                    self.con.close()
                    return
    
            except Exception, e:
                print "error:", e
                self.con.close()
                self.isConnect = False

                return

    def getIsConnect(self):
        return self.isConnect
    
    def firsStartGame(self, nRoomID):
        try:
            rgPlayers = self.m_roomManager.getPlayers(nRoomID)
            rgPlayerInfos = []
            self.m_opponents = []
            for player in rgPlayers:
                playerInfo = PlayerInfo()
                playerInfo.PlayerName = player.m_strPlayerName
                playerInfo.PlayerIcon = player.m_nPlayerIcon
                playerInfo.PlayerStartScore = player.m_nPlayerStarScore
                rgPlayerInfos.append(playerInfo)
                if (player is self) == False:
                    self.m_opponents.append(player)
            self.m_gameManage = GameManage.GameManage(self.m_roomManager, self.m_nRoomID)
            
            strStartMessage = self.m_gameManage.startGame(rgPlayerInfos)
            Take6Server.send_data(self.con, strStartMessage)
            
            for opponent in self.m_opponents:
                opponent.startGame(rgPlayers, self.m_gameManage, strStartMessage)
        except Exception, e:
            print "error:", e

    def startGame(self, players, gameManage, startMessage):
        try:
            self.m_opponents = []
            for player in players:
                if (player is self) == False:
                    self.m_opponents.append(player)
            self.m_gameManage = gameManage
            strTestMessage = startMessage
            Take6Server.send_data(self.con, strTestMessage)
        except Exception, e:
            print "error:", e

    def sendGameMessage(self, gameMessage):
        strMessage = gameMessage
        print "sendGameMessage : ", strMessage
        Take6Server.send_data(self.con, strMessage)

    def resetOpponent(self, players):
        try:
            self.m_opponents = []
            for player in players:
                if (player is self) == False:
                    self.m_opponents.append(player)
        except Exception, e:
            print "error:", e

    def breakConnectionWithOpponent(self):
        self.m_opponents = []
        self.m_gameManage = False
        self.m_nRoomID = 0

    def __pauseMessage(self):
        dicPauseMessage = OrderedDict()
        dicPauseMessage[RoomManage.KEY_MESSAGE_TYPE] = RoomManage.MessageType.ERROR_PAUSE
        
        strJsonMessage = json.dumps(dicPauseMessage)
        return strJsonMessage

    def __kickPlayerOut(self, player):
        nPlayerIndex = player.m_nPlayerIndex
        if self.__checkPlayerNeedBeKicked(nPlayerIndex):
            self.m_roomManager.playerLeftRoom(player, self.m_nRoomID)
            player.con.close()
#           Take6Server.send_data(player.con, recv_message)

    def __checkPlayerNeedBeKicked(self, playerIndex):
        rgPlayerCardDics = self.m_gameManage.m_rgReadyPlayerCard
        print "rgPlayerCardDics : ", rgPlayerCardDics
        for dicReadyCard in rgPlayerCardDics:
            if dicReadyCard[RoomManage.KEY_PLAYER_INDEX] == playerIndex:
                return False
        return True
